#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-11-21 13:24:08
# @Author  : kakarot (kakarotsun@163.com)
# @Link    : http://example.org
# @Version : $Id$

import pymongo
import datetime


def get_db():
    # 建立连接
    client = pymongo.MongoClient(host="10.244.25.180", port=27017)
    db = client['example']
    # 或者 db = client.example
    return db


def get_collection(db):
    # 选择集合（mongo中collection和database都是延时创建的）
    coll = db['informations']
    print db.collection_names()
    return coll


def insert_one_doc(db):
    # 插入一个document
    coll = db['informations']
    information = {"name": "quyang", "age": "25"}
    information_id = coll.insert(information)
    print information_id


def insert_multi_docs(db):
    # 批量插入documents,插入一个数组
    coll = db['informations']
    information = [{"name": "xiaoming", "age": "25"},
                   {"name": "xiaoqiang", "age": "24"}]
    # coll.insert_many(list())
    information_id = coll.insert(information)

    print information_id


def get_one_doc(db):
    # 有就返回一个，没有就返回None
    coll = db['informations']
    print coll.find_one()  # 返回第一条记录
    print coll.find_one({"name": "quyang"})
    print coll.find_one({"name": "none"})


def get_one_by_id(db):
    # 通过objectid来查找一个doc
    coll = db['informations']
    obj = coll.find_one()
    obj_id = obj["_id"]
    print "_id 为ObjectId类型，obj_id:" + str(obj_id)

    print coll.find_one({"_id": obj_id})
    # 需要注意这里的obj_id是一个对象，不是一个str，使用str类型作为_id的值无法找到记录
    print "_id 为str类型 "
    print coll.find_one({"_id": str(obj_id)})
    # 可以通过ObjectId方法把str转成ObjectId类型
    from bson.objectid import ObjectId

    print "_id 转换成ObjectId类型"
    print coll.find_one({"_id": ObjectId(str(obj_id))})


def get_many_docs(db):
    # mongo中提供了过滤查找的方法，可以通过各种条件筛选来获取数据集，还可以对数据进行计数，排序等处理
    coll = db['informations']
    # ASCENDING = 1 升序;DESCENDING = -1降序;default is ASCENDING
    for item in coll.find().sort("age", pymongo.DESCENDING):
        print item

    count = coll.count()
    print "集合中所有数据 %s个" % int(count)

    # 条件查询
    count = coll.find({"name": "quyang"}).count()
    print "quyang: %s" % count


def clear_all_datas(db):
    # 清空一个集合中的所有数据
    db["informations"].remove()


#唯一的字段 index
result=db.t1.create_index([('index',pymongo.ASCENDING)],unique=True)



# 查询选择器

# 比较

# 有关不同BSON类型值的比较，请参阅指定的BSON比较顺序。

# 名称  描述
# $eq 匹配等于指定值的值。
# $gt 匹配大于指定值的值。
# $gte    匹配大于或等于指定值的值。
# $in 匹配数组中指定的任何值。
# $lt 匹配小于指定值的值。
# $lte    匹配小于或等于指定值的值。
# $ne 匹配所有不等于指定值的值。
# $nin    不匹配数组中指定的值。
# 逻辑

# 名称  描述
# $and    用逻辑连接查询子句AND将返回符合两个子句条件的所有文档。
# $not    颠倒查询表达式的效果并返回与查询表达式不匹配的文档。
# $nor    用逻辑连接查询子句NOR返回所有不符合两个子句的文档。
# $or 用逻辑连接查询子句OR将返回符合任一子句条件的所有文档。
# 元素

# 名称  描述
# $exists 匹配具有指定字段的文档。
# $type   如果字段是指定的类型，则选择文档。
# 评估

# 名称  描述
# $mod    对字段的值执行模运算并选择具有指定结果的文档。
# $regex  选择值与指定正则表达式匹配的文档。
# $text   执行文本搜索。
# $where  匹配满足JavaScript表达式的文档。
# 地理空间

# 名称  描述
# $geoIntersects  选择与GeoJSON几何体相交的几何体。该2dsphere索引支持 $geoIntersects。
# $geoWithin  选择边界GeoJSON几何体中的几何体。该2dsphere和2D索引支持 $geoWithin。
# $near   返回接近点的地理空间对象。需要一个地理空间索引。该2dsphere和2D索引支持 $near。
# $nearSphere 返回接近球体上一个点的地理空间对象。需要一个地理空间索引。该2dsphere和2D索引支持 $nearSphere。
# 数组

# 名称  描述
# $all    匹配包含查询中指定的所有元素的数组。
# $elemMatch  如果数组字段中的元素匹配所有指定的$elemMatch条件，则选择文档。
# $size   如果数组字段是指定的大小，则选择文档。
# 按位

# 名称  描述
# $bitsAllClear   匹配一组位位置均具有值的数值或二进制值0。
# $bitsAllSet 匹配一组位位置均具有值的数值或二进制值1。
# $bitsAnyClear   匹配数值或二进制值，其中一组位位置中的任何位具有值0。
# $bitsAnySet 匹配数值或二进制值，其中一组位位置中的任何位具有值1。
# 评论

# 名称  描述
# $comment    向查询谓词添加注释。
# 投影算子

# 名称  描述
# $   投影与查询条件匹配的数组中的第一个元素。
# $elemMatch  投影符合指定$elemMatch条件的数组中的第一个元素。
# $meta   投影在$text操作过程中分配的文档分数。
# $slice  限制从数组投影的元素的数量。支持跳过和限制片。



查看聚集的字段
>> > db.Account.find_one({}, {"UserName": 1, "Email": 1})
{u'UserName': u'libing', u'_id': ObjectId(
    '4ded95c3b7780a774a099b7c'), u'Email': u'libing@35.cn'}


>> > db.Account.find_one({}, {"UserName": 1, "Email": 1, "_id": 0})
{u'UserName': u'libing', u'Email': u'libing@35.cn'}


查看聚集的多条记录

>> > for item in db.Account.find():
    item


>> > for item in db.Account.find({"UserName": "libing"}):
    item["UserName"]


查看聚集的记录统计
>> > db.Account.find().count()


>> > db.Account.find({"UserName": "keyword"}).count()


聚集查询结果排序
>> > db.Account.find().sort("UserName") - -默认为升序
>> > db.Account.find().sort("UserName", pymongo.ASCENDING) - -升序
>> > db.Account.find().sort("UserName", pymongo.DESCENDING) - -降序


聚集查询结果多列排序

>> > db.Account.find().sort([("UserName", pymongo.ASCENDING), ("Email", pymongo.DESCENDING)])


添加记录

>> > db.Account.insert({"AccountID": 21, "UserName": "libing"})


修改记录

>> > db.Account.update({"UserName": "libing"}, {"$set": {"Email": "libing@126.com", "Password": "123"}})


if __name__ == '__main__':
    db = get_db()
    my_collection = get_collection(db)
    post = {"author": "Mike", "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"],
            "date": datetime.datetime.utcnow()}
    # 插入记录
    my_collection.insert(post)
    insert_one_doc(db)
    # 条件查询
    print my_collection.find_one({"x": "10"})
    # 查询表中所有的数据
    for iii in my_collection.find():
        print iii
    print my_collection.count()
    my_collection.update({"author": "Mike"},
                         {"author": "quyang", "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"],
                          "date": datetime.datetime.utcnow()})
    for jjj in my_collection.find():
        print jjj
    get_one_doc(db)
    get_one_by_id(db)
    get_many_docs(db)
    # clear_all_datas(db)
